//*****************************************************************************
//
// Project 6:  Menus
//
// Authors: Aleksandar Shopov
//	Vladimir Asenov
//	Dragi Pandeliev
//
//*****************************************************************************

#include "hw_ints.h"
#include "hw_memmap.h"
#include "hw_nvic.h"
#include "hw_types.h"
#include "gpio.h"
#include "adc.h"
#include "interrupt.h"
#include "systick.h"
#include "sysctl.h"
#include "osram96x16x1.h"
#include "timer.h"
#include "uart.h"
#include "menu.h"

//
//	Defines for the project
//
#define PUSH_BUTTON			GPIO_PIN_4
#define CLICK 				1
#define DBL_CLICK 			2

//
//	Global variables 
//
short state;
short int flag, flag1;
short int tempPos;
short int tempPosR;

//
//	External variables
//
extern const short int mainMenuL[2];	// Length of each item in the menu and total number of items
extern unsigned char *pMainMenu[8];		//Pointer to the menu		
extern unsigned char mainMenu[8][32];	//The menu array
	
extern unsigned char subMenu1[6][45];
extern const short int subMenu1L[2];			 
extern unsigned char *pSubMenu1[6];

extern unsigned char subMenu2[8][45];
extern const short int subMenu2L[2];			 
extern unsigned char *pSubMenu2[8];

extern unsigned char subMenu3[4][45];
extern const short int subMenu3L[2];			 
extern unsigned char *pSubMenu3[4];

extern unsigned char subMenu4[6][47];
extern const short int subMenu4L[2];			 
extern unsigned char *pSubMenu4[6];
	
//
//	Timer0 Interrupt Function
//
void Timer0IntHandler(void)
{
	TimerIntClear(TIMER0_BASE, TIMER_TIMA_TIMEOUT);	
	++state;
}

//
//	Function for the button click
//
int ButtonState(void)
{
	short prevState = 0;
	state = 1;
	while (1)
	{
		if (prevState != state)
		{
			switch (state)
			{
				case 1: TimerLoadSet(TIMER0_BASE, TIMER_A, SysCtlClockGet()/50);
						TimerEnable(TIMER0_BASE, TIMER_A); 
						break;
			
				case 2: do
						{
						}while(!GPIOPinRead(GPIO_PORTC_BASE, PUSH_BUTTON));
						++state;
		
				case 3: TimerLoadSet(TIMER0_BASE, TIMER_A, SysCtlClockGet()/8);
						TimerEnable(TIMER0_BASE, TIMER_A);
						break;

				case 4: if (!GPIOPinRead(GPIO_PORTC_BASE, PUSH_BUTTON))
						{
							do
							{
							}while(!GPIOPinRead(GPIO_PORTC_BASE, PUSH_BUTTON));
							return DBL_CLICK;
						}
						return CLICK;
			}
		prevState = state;
		}
	}
}

int main(void)
{
	unsigned long  value, pos=0, pos1=0;
	unsigned short i;

    //
    // Set the clocking to run directly from the crystal.
    //
    SysCtlClockSet(SYSCTL_SYSDIV_10 | SYSCTL_USE_PLL | SYSCTL_OSC_MAIN |
                   SYSCTL_XTAL_6MHZ);

    //
    // Enable the peripherals used by this example.
    //
    SysCtlPeripheralEnable(SYSCTL_PERIPH_UART0);
    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);
	SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOC);
	SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER0);
	SysCtlPeripheralEnable(SYSCTL_PERIPH_ADC);
    
	//
    // Enable processor interrupts.
    //
    IntMasterEnable();

	//
	// Setting the Push button as input
	//
	GPIOPinTypeGPIOInput(GPIO_PORTC_BASE, PUSH_BUTTON);

    //
    // Set GPIO A0 and A1 as UART pins.
    //
    GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1);
    //
    // Configure the UART for 115,200, 8-N-1 operation.
    //
    UARTConfigSetExpClk(UART0_BASE, SysCtlClockGet(), 115200,
                        (UART_CONFIG_WLEN_8 | UART_CONFIG_STOP_ONE |
                         UART_CONFIG_PAR_NONE));
						 
    //
    // Initialize the OLED display
    //
    OSRAM96x16x1Init(false);
	
	//
	// Configure the 32-bit one shot timer
	//
	TimerConfigure(TIMER0_BASE, TIMER_CFG_32_BIT_OS);
	
	//
    // Setup the interrupt for the TIMER0 timeouts.
    //
    IntEnable(INT_TIMER0A);
    TimerIntEnable(TIMER0_BASE, TIMER_TIMA_TIMEOUT);
	
    //
    // Configure the ADC to sample the potentiometer when the timer expires.
    //
    ADCSequenceConfigure(ADC_BASE, 0, ADC_TRIGGER_PROCESSOR, 0);
    ADCSequenceStepConfigure(ADC_BASE, 0, 0, ADC_CTL_CH0 |  ADC_CTL_IE | ADC_CTL_END);
    ADCSequenceEnable(ADC_BASE, 0);
	
	//
	//init of the menu and submenu pointers
	//
	for (i = 0; i < 2*mainMenuL[0]; ++i)
		pMainMenu[i] = mainMenu[i];
	
	for (i = 0; i < 2*subMenu1L[0]; ++i)
		pSubMenu1[i] = subMenu1[i];

	for (i = 0; i < 2*subMenu2L[0]; ++i)
		pSubMenu2[i] = subMenu2[i];
	
	for (i = 0; i < 2*subMenu3L[0]; ++i)
		pSubMenu3[i] = subMenu3[i];
	
	for (i = 0; i < 2*subMenu4L[0]; ++i)
		pSubMenu4[i] = subMenu4[i];	
		
	//
	//first draw of menu
    //
	IntMasterDisable();
	OSRAM96x16x1ImageDraw(mainMenu[0],0,0,mainMenuL[1],1);
 	OSRAM96x16x1ImageDraw(mainMenu[1],mainMenuL[1]-1,0,mainMenuL[1],1);
 	OSRAM96x16x1ImageDraw(mainMenu[2],2*(mainMenuL[1]-1),0,mainMenuL[1],1);
	IntMasterEnable();

	while(1)
	{
		//
		// Trigger the sample sequence.
		//
		ADCProcessorTrigger(ADC_BASE, 0);
		//
		// Wait until the sample sequence has completed.
		//
		while(!ADCIntStatus(ADC_BASE, 0, false))
		{
		}
		//
		// Read the value from the ADC.
		//
		ADCSequenceDataGet(ADC_BASE, 0, &value);
		//
		// Filtering ADC values
		//
		pos = ((pos * 62659) + (value * 3276)) / 65536;

		if (((pos1 - 10) <= pos)&& (pos <= (pos1 + 10)) )
		{
		  	if ( pos >= 1 && pos <= 70 && flag != 1)		//255
			{         	   //70
				
				redrawMenu( pMainMenu,mainMenuL,0,flag,0);
				flag = 1;
			}
			if ( pos >= 71 && pos <= 511  && flag != 2)   //511
			{		  //800
				
				redrawMenu(pMainMenu,mainMenuL,1,flag,0);
				flag = 2;
			}
			if ( pos >= 512 && pos <= 767 && flag != 3)	   //767
			{		 //900
				
				redrawMenu(pMainMenu,mainMenuL,2,flag,0);
				flag = 3;
			}
			if ( pos >= 768 && pos <= 1023 && flag != 4)	//1023
			{		 //900
				
				redrawMenu(pMainMenu,mainMenuL,3,flag,0);
				flag = 4;
			}
			 
		}			 
		pos1 = pos;	
		
		if(!GPIOPinRead(GPIO_PORTC_BASE, PUSH_BUTTON)) 
		{
			if (CLICK == ButtonState())
				switch (flag)
				{
					case 1: 
					{
						unsigned long  value, pos=0, pos1=0;
						short i, cl;
					
						char funk1[] = "funkciq1";
						char funk2[] = "funkciq2";
						char funk3[] = "funkciq3";
						tempPosR = tempPos;
						tempPos = 0;
						flag1 = 0;	
						IntMasterDisable();
					 	OSRAM96x16x1ImageDraw(subMenu1[0],0,1,subMenu1L[1],1);
					  	OSRAM96x16x1ImageDraw(subMenu1[1],subMenu1L[1]-1,1,subMenu1L[1],1);
					  	OSRAM96x16x1ImageDraw(subMenu1[2],2*(subMenu1L[1]-1),1,subMenu1L[1],1);
					 	IntMasterEnable();
						while(1)
						{
							//
							//	Trigger the sample sequence.
							//
							ADCProcessorTrigger(ADC_BASE, 0);
							//
							//	Wait until the sample sequence has completed.
							//
							while(!ADCIntStatus(ADC_BASE, 0, false))
							{
							}
							//
							//	Read the value from the ADC.
							//
							ADCSequenceDataGet(ADC_BASE, 0, &value);
						  	pos = ((pos * 64659) + (value * 1276)) / 65536;
							
							if (((pos1 - 10) <= pos)&& (pos <= (pos1 + 10)) )
							{
							  	if ( pos >= 1 && pos <= 270 && flag1 != 1)	//350
								{         	 
									
									redrawMenu( pSubMenu1,subMenu1L,0,flag1,1);
									 flag1 = 1;
								}
								if ( pos > 270 && pos <= 900  && flag1 != 2)	 //900
								{	
									
									redrawMenu(pSubMenu1,subMenu1L,1,flag1,1);
									flag1 = 2;
								}
								if ( pos > 900 && pos <= 1023 && flag1 != 3)
								{	
									
									redrawMenu(pSubMenu1,subMenu1L,2,flag1,1);
									flag1 = 3;
								}
								 
							}			 
							pos1 = pos;	
							
							if(!GPIOPinRead(GPIO_PORTC_BASE, PUSH_BUTTON)) 
							{
								cl =  ButtonState();
								if (cl == CLICK)
									switch (flag1)
									{
										case 1: for (i=0; funk1[i]!='\0'; ++i) 
													UARTCharPut(UART0_BASE, funk1[i]);
												UARTCharPut(UART0_BASE, '\r');
												UARTCharPut(UART0_BASE, '\n');
												break;
										case 2: for (i=0; funk2[i]!='\0'; ++i) 
													UARTCharPut(UART0_BASE, funk2[i]);
												UARTCharPut(UART0_BASE, '\r');
												UARTCharPut(UART0_BASE, '\n');
												break;
										case 3: for (i=0; funk3[i]!='\0'; ++i) 
													UARTCharPut(UART0_BASE, funk3[i]);
												UARTCharPut(UART0_BASE, '\r');
												UARTCharPut(UART0_BASE, '\n');
									}
								else
								if (cl == DBL_CLICK)
								{
									clear_subMenu();
									tempPos = tempPosR;  
									goto exit;
								}
							}
							
						}
					
					}
					
					case 2: 
					
					{
						unsigned long  value, pos=0, pos1=0;
						short i, cl;
					
						char funk4[] = "funkciq4";
						char funk5[] = "funkciq5";
						char funk6[] = "funkciq6";
						char funk7[] = "funkciq7";
						tempPosR = tempPos;
						tempPos = 0;
						flag1 = 0;	
						IntMasterDisable();
					 	OSRAM96x16x1ImageDraw(subMenu2[0],0,1,subMenu2L[1],1);
					  	OSRAM96x16x1ImageDraw(subMenu2[1],subMenu2L[1]-1,1,subMenu2L[1],1);
					  	OSRAM96x16x1ImageDraw(subMenu2[2],2*(subMenu2L[1]-1),1,subMenu2L[1],1);
					 	IntMasterEnable();
						while(1)
						{
							//
							// Trigger the sample sequence.
							//
							ADCProcessorTrigger(ADC_BASE, 0);
							//
							// Wait until the sample sequence has completed.
							//
							while(!ADCIntStatus(ADC_BASE, 0, false))
							{
							}
							//
							// Read the value from the ADC.
							//
							ADCSequenceDataGet(ADC_BASE, 0, &value);
						  	pos = ((pos * 64659) + (value * 1276)) / 65536;
							
							if (((pos1 - 10) <= pos)&& (pos <= (pos1 + 10)) )
							{
							  	if ( pos >= 1 && pos <= 70 && flag1 != 1)
								{         	   //70
									
									redrawMenu( pSubMenu2,subMenu2L,0,flag1,1);
									 flag1 = 1;
								}
								if ( pos > 70 && pos <= 600  && flag1 != 2)
								{		  //800
									
									redrawMenu(pSubMenu2,subMenu2L,1,flag1,1);
									flag1 = 2;
								}
								if ( pos > 600 && pos <= 900 && flag1 != 3)
								{		 //900
									
									redrawMenu(pSubMenu2,subMenu2L,2,flag1,1);
									flag1 = 3;
								}
								if ( pos > 900 && pos <= 1023 && flag1 != 4)
								{		 //900
									
									redrawMenu(pSubMenu2,subMenu2L,3,flag1,1);
									flag1 = 4;
								}
								 
							}			 
							pos1 = pos;	
							
							if(!GPIOPinRead(GPIO_PORTC_BASE, PUSH_BUTTON)) 
							{
								cl =  ButtonState();
								if (cl == CLICK)
									switch (flag1)
									{
										case 1: for (i=0; funk4[i]!='\0'; ++i) 
													UARTCharPut(UART0_BASE, funk4[i]);
												UARTCharPut(UART0_BASE, '\r');
												UARTCharPut(UART0_BASE, '\n');
												break;
										case 2: for (i=0; funk5[i]!='\0'; ++i) 
													UARTCharPut(UART0_BASE, funk5[i]);
												UARTCharPut(UART0_BASE, '\r');
												UARTCharPut(UART0_BASE, '\n');
												break;
										case 3: for (i=0; funk6[i]!='\0'; ++i) 
													UARTCharPut(UART0_BASE, funk6[i]);
												UARTCharPut(UART0_BASE, '\r');
												UARTCharPut(UART0_BASE, '\n');
												break;
										case 4: for (i=0; funk7[i]!='\0'; ++i) 
													UARTCharPut(UART0_BASE, funk7[i]);
												UARTCharPut(UART0_BASE, '\r');
												UARTCharPut(UART0_BASE, '\n');
												}
								else
								if (cl == DBL_CLICK)
								{
									clear_subMenu();
									tempPos = tempPosR; 
									goto exit;
								}
							}
							
						}
					
					}
					
					
					case 3: 		
					{
						unsigned long  value, pos=0, pos1=0;
						short i, cl;
					
						char funk8[] = "funkciq8";
						char funk9[] = "funkciq9";
					
						tempPosR = tempPos;
						tempPos = 0;
						flag1 = 0;	
						IntMasterDisable();
					 	OSRAM96x16x1ImageDraw(subMenu3[0],0,1,subMenu3L[1],1);
					  	OSRAM96x16x1ImageDraw(subMenu3[1],subMenu3L[1]-1,1,subMenu3L[1],1);
					 	IntMasterEnable();

						while(1)
						{
							//
							// Trigger the sample sequence.
							//
							ADCProcessorTrigger(ADC_BASE, 0);
							//
							// Wait until the sample sequence has completed.
							//
							while(!ADCIntStatus(ADC_BASE, 0, false))
							{
							}
							//
							// Read the value from the ADC.
							//
							ADCSequenceDataGet(ADC_BASE, 0, &value);
						  	pos = ((pos * 64659) + (value * 1276)) / 65536;
							
							if (((pos1 - 10) <= pos)&& (pos <= (pos1 + 10)) )
							{
							  	if ( pos > 1 && pos <= 700 && flag1 != 1)
								{         	   //70
									redrawMenu( pSubMenu3,subMenu3L,0,flag1,1);
									 flag1 = 1;
								}
								if ( pos > 700 && pos <= 1023  && flag1 != 2)
								{		  //800
									redrawMenu(pSubMenu3,subMenu3L,1,flag1,1);
									flag1 = 2;
								}
							}			 
							pos1 = pos;	
							
							if(!GPIOPinRead(GPIO_PORTC_BASE, PUSH_BUTTON)) 
							{
								cl =  ButtonState();
								if (cl == CLICK)
									switch (flag1)
									{
										case 1: for (i=0; funk8[i]!='\0'; ++i) 
													UARTCharPut(UART0_BASE, funk8[i]);
												UARTCharPut(UART0_BASE, '\r');
												UARTCharPut(UART0_BASE, '\n');
												break;
										case 2: for (i=0; funk9[i]!='\0'; ++i) 
													UARTCharPut(UART0_BASE, funk9[i]);
												UARTCharPut(UART0_BASE, '\r');
												UARTCharPut(UART0_BASE, '\n');
												break;
									}
								else
								if (cl == DBL_CLICK)
								{
									clear_subMenu();
									tempPos = tempPosR; 
									goto exit;
								}
							}
							
						}
					
					}

					case 4: 
					{
						unsigned long  value, pos=0, pos1=0;
						short i, cl;
					
						char funk10[] = "funkciq10";
						char funk11[] = "funkciq11";
						char funk12[] = "funkciq12";
						tempPosR = tempPos;
						tempPos = 0;
						flag1 = 0;	
						IntMasterDisable();
					 	OSRAM96x16x1ImageDraw(subMenu4[0],0,1,subMenu4L[1],1);
					  	OSRAM96x16x1ImageDraw(subMenu4[1],subMenu4L[1]-1,1,subMenu4L[1],1);
					  	OSRAM96x16x1ImageDraw(subMenu4[2],2*(subMenu4L[1]-1),1,subMenu4L[1],1);
					 	IntMasterEnable();
						while(1)
						{
							//
							// Trigger the sample sequence.
							//
							ADCProcessorTrigger(ADC_BASE, 0);
							//
							// Wait until the sample sequence has completed.
							//
							while(!ADCIntStatus(ADC_BASE, 0, false))
							{
							}
							//
							// Read the value from the ADC.
							//
							ADCSequenceDataGet(ADC_BASE, 0, &value);
						  	pos = ((pos * 64659) + (value * 1276)) / 65536;
							
							if (((pos1 - 10) <= pos)&& (pos <= (pos1 + 10)))
							{
							  	if ( pos >= 1 && pos <= 270 && flag1 != 1)
								{         	   //70
									redrawMenu( pSubMenu4,subMenu4L,0,flag1,1);
									 flag1 = 1;
								}
								if ( pos > 270 && pos <= 900  && flag1 != 2)
								{		  //800
									redrawMenu(pSubMenu4,subMenu4L,1,flag1,1);
									flag1 = 2;
								}
								if ( pos > 900 && pos <= 1023 && flag1 != 3)
								{		 //900
									redrawMenu(pSubMenu4,subMenu4L,2,flag1,1);
									flag1 = 3;
								}
								 
							}			 
							pos1 = pos;	
							
							if(!GPIOPinRead(GPIO_PORTC_BASE, PUSH_BUTTON)) 
							{
								cl =  ButtonState();
								if (cl == CLICK)
									switch (flag1)
									{
										case 1: for (i=0; funk10[i]!='\0'; ++i) 
													UARTCharPut(UART0_BASE, funk10[i]);
												UARTCharPut(UART0_BASE, '\r');
												UARTCharPut(UART0_BASE, '\n');
												break;
										case 2: for (i=0; funk11[i]!='\0'; ++i) 
													UARTCharPut(UART0_BASE, funk11[i]);
												UARTCharPut(UART0_BASE, '\r');
												UARTCharPut(UART0_BASE, '\n');
												break;
										case 3: for (i=0; funk12[i]!='\0'; ++i) 
													UARTCharPut(UART0_BASE, funk12[i]);
												UARTCharPut(UART0_BASE, '\r');
												UARTCharPut(UART0_BASE, '\n');
									}
								else
								if (cl == DBL_CLICK)
								{ 
									clear_subMenu();
									tempPos = tempPosR;
									goto exit;
								}
							}
							
						}
					
					}	
				}
		}

	exit:;
			
	}

}
